from collections import OrderedDict
import os
import sys
from PyQt5.Qt import QKeySequence
from PyQt5.QtCore import QObject, pyqtSignal, Qt, QPoint
from PyQt5.QtGui import QFont, QColor, QIcon, QTextCursor, QCursor
from PyQt5.QtWidgets import QApplication, QMainWindow, QAction, QMenu, QTextEdit, QShortcut

from ui.config import cfg
from ui.function_dialog import FuncionDialog
from ui.utils import import_module, load_config

from function import *
import icon_main


class ConsoleStream(QObject):
    textSignal = pyqtSignal(str)

    def write(self, text):
        self.textSignal.emit(str(text))
        QApplication.processEvents()

class MainWindow(QMainWindow):

    def __init__(self, config='.config.json'):
        super(MainWindow, self).__init__(None)
        self.cfg = config
        self.config = OrderedDict(cfg)

        self.thirdPartyConfig()

        if os.path.exists(config):
            print("Initial GUI with config", config)
            config = load_config(config)
            self.config.update(config)
        
        self.threadlist = []
        self.initGUI()
        sys.stdout = ConsoleStream(textSignal=self.redirectStream)

    def initGUI(self,):
        self.setWindowIcon(QIcon(':/m13.ico'))
        self.setWindowTitle("AI建模工具")
        self.createConsole()
        self.createMenu()

        self.resize(800,600)
        self.show()

    def createMenu(self,):
        for menuName, actions in self.config.items():
            menu = QMenu(menuName,self)
            for title, config in actions.items():
                function = config['function']
                try:
                    if not 'configs' in config:
                        if isinstance(function, str):
                            function = eval(function)
                        action = QAction(title, self, triggered=function)
                        # action
                        if '停止程序' in title:
                            QShortcut(QKeySequence('Ctrl+T'), self, self.stopAllThread)
                        menu.addAction(action)
                    else:
                        script = config['script']
                        try:
                            function = import_module(script, function)
                        except:
                            function = eval(function)
                        def clickAction(ignore=None,function=function, cfgpath=os.path.join(os.path.abspath('.'), '.config.json'), 
                                menuName=menuName, title=title, config=self.config, parent=self):
                            function_dialog = FuncionDialog(
                                function, cfgpath, menuName, title, config, parent, threadlist=self.threadlist)
                            function_dialog.show()
                        action = QAction(title, self, triggered=clickAction)
                        if '(' in title and ')' in title:
                            QShortcut(QKeySequence(title.split('(')[1].split(')')[0]), self, clickAction)
                        menu.addAction(action)
                except:
                    def fun(self,title=title):
                        print('未实现功能', title)
                    action = QAction(title, self, triggered=fun)
                    menu.addAction(action)
                if 'addSeparator' in config:
                    if config['addSeparator'].lower() == 'true':
                        menu.addSeparator()
            menu.setStyleSheet("font:255 11pt '新宋体'") # background:rgb(200, 200, 200);
            self.menuBar().addMenu(menu)
        # "background:rgb(255,255,0, 60);font:75 11pt '新宋体'"
        self.menuBar().setStyleSheet("font:75 12pt '新宋体' Bold;border:1px solid #014F84") # background:rgb(0, 0, 0, 32);
        # self.menuBar().setStyleSheet("QTableWidget{background-color: black;border:20px solid #014F84}")
        #"QTableWidget::item{border:1px solid #014F84}")

    def thirdPartyConfig(self):
        # "lambda x: os.system('labelme')"

        cfg = {"功能设置": {"脚本配置": {"function": "self.printScriptConfig"},
                          "停止程序": {"function": 'self.stopAllThread'},
                         }
                    }
        if not '功能设置' in self.config:
            cfg.update(self.config)
            self.config = deepcopy(cfg)
            return
        self.config['功能设置'].update(cfg['功能设置'])


    def createConsole(self):
        font = QFont()
        font.setFamily('Courier')
        font.setFixedPitch(True)
        font.setPointSize(10)

        # self.consoleBrowser = QTextEdit(self, readOnly=True)
        self.consoleBrowser = TextEdit(self, readOnly=True)
        self.consoleBrowser.setFont(font)

        def clearConsle(*args):
            self.consoleBrowser.setText('')

        QShortcut(QKeySequence('Backspace'), self, clearConsle)

        self.setCentralWidget(self.consoleBrowser)
        self.consoleBrowser.setStyleSheet("background:rgb(25,25,25)")
        self.setWindowOpacity(0.98)

    def redirectStream(self, text):
        """Write console output to text widget."""
        self.consoleBrowser.moveCursor(QTextCursor.End)
        self.consoleBrowser.setTextColor(QColor(0, 255, 0))
        self.consoleBrowser.textCursor().insertText(text)
        self.consoleBrowser.setTextCursor(self.consoleBrowser.textCursor())
        self.consoleBrowser.ensureCursorVisible()

    def closeEvent(self, event):
        """Shuts down application on close."""
        # Return stdout to defaults.
        sys.stdout = sys.__stdout__
        super().closeEvent(event)

    def printScriptConfig(self):
        cfg = os.path.join(os.path.abspath('.'), '.config.json')
        from collections import OrderedDict

        config = OrderedDict(self.config)
        with open(cfg, 'w', encoding='utf-8') as fp:
            json.dump(config, fp=fp, ensure_ascii=False)
        print('脚本配置信息详见（%s）\n可在配置文件中增改自定义功能.' % cfg)

    def stopAllThread(self):
        for thread in self.threadlist:
            if thread is not None:
                if thread.isRunning():
                    thread.terminate()
                    # thread.quit()
                    thread.exit()
        self.threadlist.clear()

class TextEdit(QTextEdit):

    signal_evoke_kb = pyqtSignal()

    def __init__(self, *args, **kwargs):
        super(TextEdit, self).__init__(*args, **kwargs)
        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.customContextMenuRequested[QPoint].connect(
            self.myListWidgetContext)

    def mouseMoveEvent(self, QMouseEvent):
        super(TextEdit, self).mouseMoveEvent(QMouseEvent)
        x = QMouseEvent.x()
        w = self.width()
        if w - x <= 20:
            self.verticalScrollBar().show()
        else:
            self.verticalScrollBar().hide()
        self.signal_evoke_kb.emit()

    #自定义右键按钮
    def myListWidgetContext(self):
        popMenu = QMenu()
        popMenu.addAction(QAction('清空信息窗', self))
        popMenu.triggered[QAction].connect(self.processtrigger)
        popMenu.exec_(QCursor.pos())

    #右键按钮事件
    def processtrigger(self, q=''):
        text = self.toPlainText()
        if not text.strip():
            return
        if q.text() == "清空信息窗":
            self.setText("")

if __name__ == '__main__':
    app = QApplication(sys.argv)
    main = MainWindow()
    main.show()
    sys.exit(app.exec_())
    # 